Trying to detect client dropping connection before CGI process is
am 22.10.2009 00:18:15 von Fi Dot--0016e68ea4fbf388260476795a5a
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Dear All,
I seem to be completely stuck with trying to detect client dropping
connection, no matter how hard I try.
I start with a simple Perl script running as a standard CGI app:
#!/usr/bin/perl
use strict;
Log("$$: starting process");
$SIG{PIPE} =3D sub { Log("$$: PIPE!!"); };
$SIG{TERM} =3D sub { Log("$$: TERM!!"); };
$SIG{HUP} =3D sub { Log("$$: HUP"); };
$SIG{INT} =3D sub { Log("$$: INT"); };
Log("$$: Processing request");
print "\n\n";
for(1 .. 10)
{
Log("$$: Sleep $_ ");
sleep(1);
}
print "Content\n";
Log("$$: Done");
I also have tried the following modification of the script for mod_perl:
#!/usr/bin/perl
use strict;
use Apache2::RequestRec;
use Apache2::Connection;
Log("$$: starting process");
$SIG{PIPE} =3D sub { Log("$$: PIPE!!"); };
$SIG{TERM} =3D sub { Log("$$: TERM!!"); };
$SIG{HUP} =3D sub { Log("$$: HUP"); };
$SIG{INT} =3D sub { Log("$$: INT"); };
local our $Conn =3D Apache2::RequestRec->connection();
Log("$$: Processing request");
print "\n\n";
for(1 .. 10)
{
Log("$$: Sleep $_, aborted:", $Conn->aborted());
sleep(1);
}
print "Content\n";
Log("$$: Done");
and another modification for mod_fcgid (same idea with trying to intercept
signals and both with and w/o trying to use Apache2::Connection).
Log() function just outputs messages to a log file, that i am tail -f 'ing.
I make a request using curl,
curl http://localhost/script.pl
and also have tried LWP::UserAgent.
The way I test it is run the request process (either curl or a simple .pl
with a request made via LWP::UserAgent), and Control-C at some point (while
watching 'Sleep XX' messages appear in the log file).
In all three cases with both LWP and curl i see the same behavior - no
indication of a client dropping the connection (even with aborted() method
of mod_perl) whatsoever, no signals, no messages about client dropping
connection appearing in error.log of the server (LogLevel is set to 'info')=
,
etc. The CGI process in CGI case doesn't get terminated and / or killed; it
continues to loop and sleep until 10 seconds pass.
From what I have been able to find, I tried:
* Looks like adding print STDOUT in the loop should cause PIPE signal
('broken pipe'), I tried adding 'print STDOUT " "' right before sleep() cal=
l
in the loop with no luck.
* Trying to see if the same print before sleep() would return failure
('print STDOUT " " or Log("Print failed!")', w/o any luck
* In mod_perl tests, trying to use Apache2::RequestRec->print() instead of
print.
* LogLevel info should be giving me messages about clients dropping
connections in error.log. I am not seeing any.
In addition, I clearly recall solving the same problem under mod_perl and
Apache using $Conn->aborted() method, and it worked (but that was a
different version of Apache 2 and mod_perl, unfortunately, I donâ=99t =
have that
env right now to compareâ=A6).
I have tried this on 2 versions of Apache and mod_perl,
* Ubuntu + apache 2.2.8 / mod_perl 2.0.3:
root@vmubuntu ~/api # apache2 -V
Server version: Apache/2.2.8 (Ubuntu)
Server built: Feb 2 2008 04:03:01
Server's Module Magic Number: 20051115:11
Server loaded: APR 1.2.11, APR-Util 1.2.12
Compiled using: APR 1.2.11, APR-Util 1.2.12
Architecture: 32-bit
Server MPM: Prefork
threaded: no
forked: yes (variable process count)
Server compiled with....
-D APACHE_MPM_DIR=3D"server/mpm/prefork"
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=3D128
-D HTTPD_ROOT=3D""
-D SUEXEC_BIN=3D"/usr/lib/apache2/suexec"
-D DEFAULT_PIDLOG=3D"/var/run/apache2.pid"
-D DEFAULT_SCOREBOARD=3D"logs/apache_runtime_status"
-D DEFAULT_LOCKFILE=3D"/var/run/apache2/accept.lock"
-D DEFAULT_ERRORLOG=3D"logs/error_log"
-D AP_TYPES_CONFIG_FILE=3D"/etc/apache2/mime.types"
-D SERVER_CONFIG_FILE=3D"/etc/apache2/apache2.conf"
* Gentoo + apache 2.2.11 + mod_perl 2.0.4:
newcore tmp # apache2 -V
Server version: Apache/2.2.11 (Unix)
Server built: Oct 21 2009 16:42:25
Server's Module Magic Number: 20051115:21
Server loaded: APR 1.2.8, APR-Util 1.2.8
Compiled using: APR 1.2.8, APR-Util 1.2.8
Architecture: 32-bit
Server MPM: Prefork
threaded: no
forked: yes (variable process count)
Server compiled with....
-D APACHE_MPM_DIR=3D"server/mpm/prefork"
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=3D128
-D HTTPD_ROOT=3D"/usr"
-D SUEXEC_BIN=3D"/usr/sbin/suexec"
-D DEFAULT_PIDLOG=3D"/var/run/httpd.pid"
-D DEFAULT_SCOREBOARD=3D"logs/apache_runtime_status"
-D DEFAULT_LOCKFILE=3D"/var/run/accept.lock"
-D DEFAULT_ERRORLOG=3D"logs/error_log"
-D AP_TYPES_CONFIG_FILE=3D"/etc/apache2/mime.types"
-D SERVER_CONFIG_FILE=3D"/etc/apache2/httpd.conf"
As you can see, both servers are running prefork mpm.
Would anyone have a suggestion for this problem? Ideally I would like
either to be able to somehow detect client dropping connection from his sid=
e
from within the script, or Apache itself just killing the worker / CGI
process whenever it detects that.
Fi.
--0016e68ea4fbf388260476795a5a
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx">
" href=3D"file:///C:%5CUsers%5CFFOMIC%7E1%5CAppData%5CLocal%5C Temp%5Cmsohtm=
lclip1%5C01%5Cclip_colorschememapping.xml">
Dear All,
Â
Â
I seem to be completely stuck with trying to detect =
client
dropping connection, no matter how hard I try.
Â
I start with a simple Perl script running as a stand=
ard CGI
app:
Â
  #!/usr/bin/perl=
Â
  use strict;
Â
  Log("$$:
starting process");
Â
  $SIG{PIPE} =3D =
sub {
Log("$$: PIPE!!"); };
  $SIG{TERM} =3D =
sub {
Log("$$: TERM!!");Â };
  $SIG{HUP} =3D s=
ub {
Log("$$: HUP"); };
  $SIG{INT} =3D s=
ub {
Log("$$: INT"); };
Â
  Log("$$: P=
rocessing
request");
Â
  print
"\n\n";
Â
  for(1 .. 10) =
p>
  {
    Log=
("$$:
Sleep $_ ");
    sle=
ep(1);
  }
Â
  print
"Content\n";
Â
  Log("$$:
Done");
Â
Â
I also have tried the following modification of the =
script
for mod_perl:
Â
Â
  #!/usr/bin/perl=
Â
  use strict;
Â
  use
Apache2::RequestRec;
  use
Apache2::Connection;
Â
  Log("$$:
starting process");
Â
  $SIG{PIPE} =3D =
sub {
Log("$$: PIPE!!"); };
  $SIG{TERM} =3D =
sub {
Log("$$: TERM!!");Â };
  $SIG{HUP} =3D s=
ub {
Log("$$: HUP"); };
  $SIG{INT} =3D s=
ub { Log("$$:
INT"); };
Â
  local our $Conn=
=3D
Apache2::RequestRec->connection();
Â
  Log("$$:
Processing request");
Â
  print
"\n\n";
Â
  for(1 .. 10) =
p>
  {
    Log=
("$$:
Sleep $_, aborted:", $Conn->aborted());
    sle=
ep(1);
  }
Â
  print
"Content\n";
Â
  Log("$$:
Done");
Â
Â
and another modification for mod_fcgid (same idea wi=
th
trying to intercept signals and both with and w/o trying to use Apache2::Co=
nnection).
Â
Log() function just outputs messages to a log file, =
that i
am tail -f 'ing.
Â
Â
I make a request using curl,
Â
curl http://l=
ocalhost/script.pl
Â
and also have tried LWP::UserAgent.
Â
The way I test it is run the request process (either=
curl or
a simple .pl with a request made via LWP::UserAgent), and Control-C at some
point (while watching 'Sleep XX' messages appear in the log file). =
Â
In all three cases with both LWP and curl i see the =
same
behavior - no indication of a client dropping the connection (even with
aborted() method of mod_perl) whatsoever, no signals, no messages about cli=
ent
dropping connection appearing in error.log of the server (LogLevel is set t=
o
'info'), etc. The CGI process in CGI case doesn't get terminate=
d and / or
killed; it continues to loop and sleep until 10 seconds pass.
Â
Â
From what I have been able to find, I tried:
Â
* Looks like adding print STDOUT in the loop should =
cause
PIPE signal ('broken pipe'), I tried adding 'print STDOUT "=
; "' right
before sleep() call in the loop with no luck.
* Trying to see if the same print before sleep() wou=
ld
return failure ('print STDOUT " " or Log("Print failed!&=
quot;)',
w/o any luck
* In mod_perl tests, trying to use
Apache2::RequestRec->print() instead of print.
* LogLevel info should be giving me messages about c=
lients
dropping connections in error.log. I am not seeing any.
Â
Â
In addition, I clearly recall solving the same probl=
em under
mod_perl and Apache using $Conn->aborted() method, and it worked (but th=
at
was a different version of Apache 2 and mod_perl, unfortunately, I don=E2=
t have
that env right now to compareâ=A6).
Â
I have tried this on 2 versions of Apache and mod_pe=
rl,
Â
* Ubuntu + apache 2.2.8 / mod_perl 2.0.3:
Â
 root@vmubuntu ~/api
# apache2 -V
 Server version:
Apache/2.2.8 (Ubuntu)
 Server built:
yle=3D"">  Feb 2
2008 04:03:01
 Server's Module
Magic Number: 20051115:11
 Server loaded: tyle=3D""> APR 1.2.11, APR-Util 1.2.12
 Compiled using: APR
1.2.11, APR-Util 1.2.12
 Architecture: yle=3D"">  32-bit
 Server MPM: e=3D"">    Prefork
   threaded:=
    no
    Â
an>forked:Â Â Â Â yes (variable pr=
ocess count)
 Server compiled
with....
  -D
APACHE_MPM_DIR=3D"server/mpm/prefork"
  -D APR_HAS_SEND=
FILE
  -D APR_HAS_MMAP=
  -D APR_HAVE_IPV=
6
(IPv4-mapped addresses enabled)
  -D
APR_USE_SYSVSEM_SERIALIZE
  -D
APR_USE_PTHREAD_SERIALIZE
  -D
SINGLE_LISTEN_UNSERIALIZED_ACCEPT
  -D
APR_HAS_OTHER_CHILD
  -D
AP_HAVE_RELIABLE_PIPED_LOGS
  -D
DYNAMIC_MODULE_LIMIT=3D128
  -D
HTTPD_ROOT=3D""
  -D
SUEXEC_BIN=3D"/usr/lib/apache2/suexec"
  -D
DEFAULT_PIDLOG=3D"/var/run/apache2.pid"
  -D DEFAULT_SCOR=
EBOARD=3D"logs/apache_runtime_status"
  -D
DEFAULT_LOCKFILE=3D"/var/run/apache2/accept.lock"
  -D
DEFAULT_ERRORLOG=3D"logs/error_log"
  -D
AP_TYPES_CONFIG_FILE=3D"/etc/apache2/mime.types"
  -D
SERVER_CONFIG_FILE=3D"/etc/apache2/apache2.conf"
Â
* Gentoo + apache 2.2.11 + mod_perl 2.0.4:
Â
  newcore tmp #
apache2 -V
  Server version:
Apache/2.2.11 (Unix)
  Server built:
pan style=3D"">Â Â Oct 21 2009 16:42:25
  Server's Mo=
dule
Magic Number: 20051115:21
  Server loaded:<=
span style=3D"">Â APR 1.2.8, APR-Util 1.2.8
  Compiled using:=
APR
1.2.8, APR-Util 1.2.8
  Architecture:
pan style=3D"">Â Â 32-bit
  Server MPM:
    thr=
eaded:Â Â Â Â no
     =C2=
=A0 forked:Â Â Â Â yes (var=
iable process count)
  Server compiled
with....
   -D
APACHE_MPM_DIR=3D"server/mpm/prefork"
   -D
APR_HAS_SENDFILE
   -D APR_HA=
S_MMAP
   -D APR_HA=
VE_IPV6
(IPv4-mapped addresses enabled)
   -D
APR_USE_SYSVSEM_SERIALIZE
   -D
APR_USE_PTHREAD_SERIALIZE
   -D
SINGLE_LISTEN_UNSERIALIZED_ACCEPT
   -D
APR_HAS_OTHER_CHILD
   -D
AP_HAVE_RELIABLE_PIPED_LOGS
   -D
DYNAMIC_MODULE_LIMIT=3D128
 =C2=
Â=A0-D HTTPD_ROOT=3D"/usr"
   -D
SUEXEC_BIN=3D"/usr/sbin/suexec"
   -D
DEFAULT_PIDLOG=3D"/var/run/httpd.pid"
   -D
DEFAULT_SCOREBOARD=3D"logs/apache_runtime_status"
   -D
DEFAULT_LOCKFILE=3D"/var/run/accept.lock"
   -D
DEFAULT_ERRORLOG=3D"logs/error_log"
   -D AP_TYP=
ES_CONFIG_FILE=3D"/etc/apache2/mime.types"
   -D
SERVER_CONFIG_FILE=3D"/etc/apache2/httpd.conf"
Â
Â
Â
As you can see, both servers are running prefork mpm=
..
 Would anyone have a suggestion for this proble=
m? Ideally I would like either to be able to somehow detect client droppin=
g connection from his side from within the script, or Apache itself just ki=
lling the worker / CGI process whenever it detects that.
Fi.
Â
Â
Â
Â
Â
Â
--0016e68ea4fbf388260476795a5a--